//
//  ZQQRemoteResourceLoaderDelegate.m
//  播放器
//
//  Created by MoDao-iOS on 2017/7/19.
//  Copyright © 2017年 MoDao-iOS. All rights reserved.
//

#import "ZQQRemoteResourceLoaderDelegate.h"
#import "ZQQAudioDownLoader.h"
#import "ZQQRemoteAudioFile.h"
#import "NSURL+ZQQ.h"

@interface ZQQRemoteResourceLoaderDelegate ()<ZQQAudioDownLoaderDelegate>

@property (nonatomic, strong) ZQQAudioDownLoader *downLoader;

/** 所有的loadingRequests数组 */
@property (nonatomic, strong) NSMutableArray<AVAssetResourceLoadingRequest *> *loadingRequests;

@end

@implementation ZQQRemoteResourceLoaderDelegate

- (ZQQAudioDownLoader *)downLoader {
    if (!_downLoader) {
        _downLoader = [[ZQQAudioDownLoader alloc] init];
        _downLoader.delegate = self;
    }
    return _downLoader;
}

- (NSMutableArray<AVAssetResourceLoadingRequest *> *)loadingRequests {
    if (!_loadingRequests) {
        _loadingRequests = [NSMutableArray array];
    }
    return _loadingRequests;
}

// 当外界要播放一段音频时，会抛一个请求，给这个对象
// 这个对象，到时候，只需要根据请求信息，抛数据给外界
- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest {
    NSLog(@"%@", loadingRequest);
    // 记录所有的请求
    [self.loadingRequests addObject:loadingRequest];
    
    // 1. 判断, 本地有没有该音频资源的缓存文件, 如果有 -> 直接根据本地缓存, 向外界响应数据(3个步骤) return
    NSURL *url = [loadingRequest.request.URL httpURL];
    // 请求开始的偏移量
    long long requestOffset = self.loadingRequests.firstObject.dataRequest.currentOffset;
    // 请求过程中的偏移量
//    long long currentOffset = loadingRequest.dataRequest.currentOffset;
//    if (requestOffset != currentOffset) {
//        requestOffset = currentOffset;
//    }
    
    // 本地缓存已下载好
    if ([ZQQRemoteAudioFile cacheFileExists:url]) {
        [self handleLoadingRequest:loadingRequest];
        return YES;
    }
    
    
    // 2. 判断有木有正在下载的
    // 没有
    if (self.downLoader.loadedSize == 0) {
        [self.downLoader downLoadWithURL:url offset:requestOffset];
        return YES;
    }
    
    // 3. 判断当前是否需要重新下载
    // 3.1 当资源请求，开始点(正在下载的开始的) < 下载的开始点（已缓存文件的下载点）
    // 3.2 开始点 > 下载的开始的 + 下载的长度 + 666
    if (requestOffset < self.downLoader.offset || requestOffset > (self.downLoader.offset + self.downLoader.loadedSize + 666)) {
        [self.downLoader downLoadWithURL:url offset:requestOffset];
        return YES;
    }
    
    // 开始处理资源请求 (在下载过程中，也要不断的判断), 就是不断给外界抛数据
    [self handleAllLoadingRequest];
    
    return YES;
}

// 取消请求
- (void)resourceLoader:(AVAssetResourceLoader *)resourceLoader didCancelLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest {
    NSLog(@"取消某个请求");
    [self.loadingRequests removeObject:loadingRequest];
}

// 处理所有的请求
- (void)handleAllLoadingRequest {
    NSLog(@"-----%@", self.loadingRequests);
//    NSMutableArray *deleteRequests = [NSMutableArray array];
//    for (AVAssetResourceLoadingRequest *loadingRequest in self.loadingRequests) {
        AVAssetResourceLoadingRequest *loadingRequest = self.loadingRequests.firstObject;
        // 1. 填充信息头
        NSURL *url = loadingRequest.request.URL;
        long long totalSize = self.downLoader.totalSize;
        loadingRequest.contentInformationRequest.contentLength = totalSize;
        NSString *contentType = self.downLoader.mimeType;
        loadingRequest.contentInformationRequest.contentType = contentType;
        loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES;
        
        // 2.填充数据
        NSData *data = [NSData dataWithContentsOfFile:[ZQQRemoteAudioFile tmpFilePath:url] options:NSDataReadingMappedIfSafe error:nil];
        if (data.length == 0) {
            data = [NSData dataWithContentsOfFile:[ZQQRemoteAudioFile cacheFilePath:url] options:NSDataReadingMappedIfSafe error:nil];
        }
        
//        long long requestOffset = loadingRequest.dataRequest.requestedOffset;
        long long requestOffset = loadingRequest.dataRequest.currentOffset;
//        if (requestOffset != currentOffset) {
//            requestOffset = currentOffset;
//        }
        NSInteger requestLength = loadingRequest.dataRequest.requestedLength;
        
        long long responserOffset = requestOffset - self.downLoader.offset;
        long long responseLength = MIN(self.downLoader.offset + self.downLoader.loadedSize - requestOffset, requestLength);
        
        NSData *rangeData = [data subdataWithRange:NSMakeRange(responserOffset,responseLength)];
        
        [loadingRequest.dataRequest respondWithData:rangeData];
        
        // 3. 完成请求(必须把所有的关于这个请求的区间数据, 都返回完之后, 才能完成这个请求)
        if (requestLength == responseLength) {
            [loadingRequest finishLoading];
            [self.loadingRequests removeObject:loadingRequest];
        }
//    }
    // 删除无用的请求
//    [self.loadingRequests removeObjectsInArray:deleteRequests];
}

#pragma mark ====正在下载的代理方法
- (void)downLoading {
    [self handleAllLoadingRequest];
}

#pragma mark - 私有方法
// 处理, 本地已经下载好的资源文件
- (void)handleLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest {
    // 1. 填充相应的信息头信息
    
    // 计算总大小
    NSURL *url = loadingRequest.request.URL;
    long long totalSize = [ZQQRemoteAudioFile cacheFileSize:url];
    loadingRequest.contentInformationRequest.contentLength = totalSize;
    
    loadingRequest.contentInformationRequest.contentType = [ZQQRemoteAudioFile contentType:url];
    loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES;
    
    // 2. 相应数据给外界
    NSError *error = nil;
    NSData *data = [NSData dataWithContentsOfFile:[ZQQRemoteAudioFile cacheFilePath:url] options:NSDataReadingMappedIfSafe error:&error];
    if (error) {
        NSLog(@"%@",error);
    }
    
    long long requestOffset = loadingRequest.dataRequest.requestedOffset;
    NSInteger requestLenghth = loadingRequest.dataRequest.requestedLength;
    
    NSData *rangeData = [data subdataWithRange:NSMakeRange(requestOffset, requestLenghth)];
    [loadingRequest.dataRequest respondWithData:rangeData];
    
    // 3. 完成本次请求(一旦所有的数据都给完了，才能完成请求)
    [loadingRequest finishLoading];
}
@end
